/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { ClassDeclaration } from 'ts-morph';
import { ClassAnalysis, DecoratorConstants, Logger } from '..';
import { ClassAnalyzer } from '../analyzers/ClassAnalyzer';
import { TsMorphUtil } from '../utils/TsMorphUtil';

export class CodeAnalysisService {
  constructor() { }

  analyzeFile(filePath: string): ClassAnalysis[] {
    Logger.debug(`开始分析文件: ${filePath}`);

    const sourceFile = TsMorphUtil.getProject().addSourceFileAtPath(filePath);
    const classes = sourceFile.getClasses();
    const results: ClassAnalysis[] = [];

    for (const cls of classes) {
      const classAnalysis = this.analyzeClass(cls);
      if (classAnalysis) {
        results.push(classAnalysis);
      } else {
        Logger.debug(`${cls.getName()}无@Serializable装饰器，跳过分析`);
      }
    }

    Logger.debug(`文件分析完成: ${filePath}, 发现 ${results.length} 个@Serializable类`);

    return results;
  }

  private analyzeClass(cls: ClassDeclaration): ClassAnalysis | null {
    const decorators = cls.getDecorators();

    for (const decorator of decorators) {
      if (decorator.getName() === DecoratorConstants.SERIALIZABLE) {
        // 找到@Serializable装饰器，开始分析
        return ClassAnalyzer.analyzeClass(cls);
      }
    }

    // 没有@Serializable装饰器，跳过
    return null;
  }

  dispose(): void {
    // 清理项目资源
    const sourceFiles = TsMorphUtil.getProject().getSourceFiles();
    Logger.info(`code analysis Clearing ${sourceFiles.length} source files...`);
    sourceFiles.forEach((sourceFile) => {
      TsMorphUtil.getProject().removeSourceFile(sourceFile);
    });
  }
}
